package api

import (
	"LibraryManagementSys/gorm/dbm"
	"LibraryManagementSys/internal/pkg/rep"
	"LibraryManagementSys/internal/service"
	"LibraryManagementSys/model/dto"
	"LibraryManagementSys/pkg/util"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
	"net/http"
)

var UserApi = &userApi{}

type userApi struct{}

// Register 用户注册
// @Summary     用户注册
// @Description 用户注册, Post 请求, 注册信息在消息体中
// @Tags        UserApi
// @Accept      json
// @Produce     json
// @Param       registerParam body     dto.RegisterParam true "前端发送的 Json 对象"
// @Success     200           {string} string            "answer"
// @Failure     400           {string} string            "ok"
// @Failure     404           {string} string            "ok"
// @Failure     500           {string} string            "ok"
// @Router      /user/register [post]
func (userApi) Register(ctx *gin.Context) {
	var param dto.RegisterParam
	err := ctx.ShouldBindJSON(&param)
	if err != nil {
		errs := err.(validator.ValidationErrors)
		fmt.Println(errs)
		ctx.JSON(400, gin.H{
			"msg": util.RemoveTopStruct(errs.Translate(util.Trans)),
		})

		zap.S().Errorf("绑定参数失败: %s", errs)
		return
	}
	err = service.UserService.Register(&param)
	if err != nil {
		zap.S().Errorf("用户注册失败: %s", err)
		rep.InternalServerError(ctx, "用户注册失败")
		return
	}

	rep.Ok(ctx, "注册用户成功", nil)

}

// Login 用户登陆
// @Summary     用户登陆
// @Description 用户登陆, Post 请求, 登陆信息在消息体中
// @Tags        UserApi
// @Accept      json
// @Produce     json
// @Param       registerParam body     dto.LoginParam true "前端发送的 Json 对象"
// @Success     200           {string} string         "answer"
// @Failure     400           {string} string         "ok"
// @Failure     404           {string} string         "ok"
// @Failure     500           {string} string         "ok"
// @Router      /user/login [post]
func (userApi) Login(ctx *gin.Context) {
	var param dto.LoginParam
	if err := ctx.ShouldBindJSON(&param); err != nil {
		zap.S().Errorf("绑定失败: %s", err)
		rep.InternalServerError(ctx, err.Error())
		return
	}

	fmt.Println(param)

	token, err := service.UserService.Login(&param)
	if err != nil {
		zap.S().Errorf("用户登录失败: %s", err)
		rep.InternalServerError(ctx, err.Error())
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"token": token,
	})
}

// TestAuth 访问这个接口的时候，用户必须是已经登陆过的
// @Summary     访问这个接口的时候，用户必须是已经登陆过的
// @Description 访问这个接口的时候，用户必须是已经登陆过的
// @Tags        UserApi
// @Accept      json
// @Produce     json
// @Success     200           {string} string         "answer"
// @Failure     400           {string} string         "ok"
// @Failure     404           {string} string         "ok"
// @Failure     500           {string} string         "ok"
// @Router      /user/testAuth [get]
// @Security ApiKeyAuth
func (userApi) TestAuth(ctx *gin.Context) {
	object, exists := ctx.Get("user")
	if !exists {
		zap.L().Info("从gin.Context中获取用户信息失败")
		return
	}
	user, ok := object.(dbm.User)
	if !ok {
		zap.L().Info("将 any 转成 user 对象失败")
		return
	}
	zap.L().Info("从gin.Context 中获取的 User 对象成功",
		zap.Int("id", user.ID),
		zap.String("username", user.Username),
		zap.String("password", user.Password),
		zap.Bool("sex", user.Sex),
		zap.String("phone", user.Phone),
		zap.String("email", user.Email),
		zap.Time("createTime", user.CreateTime),
		zap.Time("updateTime", user.UpdateTime),
	)
}
